home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
pc
/
files
/
dsp
/
56200tar.z
/
56200tar
/
56200
/
p5
< prev
next >
Wrap
Text File
|
1992-04-28
|
25KB
|
510 lines
/***********************************************\
|** **|
|** DSP56200 CHIP DRIVER -ADAPTIVE FILTER **|
|** -POLLED I/O **|
|** **|
\***********************************************/
/************************************************************************\
* *
* This is an example of a program located in a host processor, used *
* to setup and service the DSP56200 as a real-time adaptive filter. *
* In this example, the host processor polls a general purpose input *
* pin to determine the beginning of a new sample period, signified *
* by the reception of a rising edge on the DSP56200's START pin. The *
* general purpose input pin is tied directly to the START pin of the *
* DSP56200. *
* *
* This program, written in the language "C", is provided only as an *
* example, and will be much faster if translated by the user into the *
* assembly language of the host processor. *
* *
* *
* The example system is configured as shown below: *
* *
* *
* ------------ *
* | DSP56200 | *
* ------------ *
* ^ *
* | *
* v *
* ------- ------------------ *
* d(t) -->| A/D |--->| Host Processor | *
* ------- | | ------- *
* | (contains code |--->| D/A |--> out(t) *
* ------- | found in this | ------- *
* x1(t) -->| A/D |--->| file) | *
* ------- ------------------ *
* *
* *
* Figure 1. Adaptive Filtering System *
* *
* *
* *
* There is only one DSP56200 in this example (i.e., not multiple *
* DSP56200s in cascade), and it is configured as an adaptive filter *
* (see Figure 2) by writing the DSP56200's Configuration register. *
* Since only 16 bits of the result are sent to the D/A Converter, *
* the output is rounded to a 16 bit result by the DSP56200. *
* *
* *
* *
* *
* d(n) ------------------------------- *
* - | *
* v *
* -------------- + --- *
* x1(n) ----->| FIR |------->| + |-----> out(n) *
* | Structure | --- = -1 * error *
* -------------- | *
* ^ | *
* | | *
* ------------------- *
* *
* *
* Figure 2. DSP56200 Configuration *
* *
* *
* *
* ************************************************************ *
* * * *
* * This program originally available on the Motorola DSP * *
* * bulletin board. It is provided under a DISCLAMER OF * *
* * WARRANTY available from Motorola DSP Operation, * *
* * 6501 Wm. Cannon Drive W., Austin, Tx., 78735. * *
* * * *
* ************************************************************ *
* *
* *
* *
* *
* ************************************************************ *
* * Note on the Representation of Hex Numbers: * *
* * * *
* * In the programming language "C", hex numbers are * *
* * represented by preceding the number with "0x". For * *
* * example, e4 (hex) is represented in "C" as 0xe4. * *
* * * *
* ************************************************************ *
* *
\************************************************************************/
/*** CONSTANTS ***/
#define FOREVER 1 /* For infinite looping */
#define X1_HI 0x0 /* Addresses (hex) of DSP56200 regs, bank 0 */
#define X1_LO 0x1
#define D_HI 0x2
#define D_LO 0x3
#define K_HI 0x4
#define K_LO 0x5
#define X2_HI 0x6 /* unused -Dual FIR mode only */
#define X2_LO 0x7 /* unused -Dual FIR mode only */
#define DATA_HI 0x8 /* unused */
#define DATA_LO 0x9 /* unused */
#define COEFF_HI 0xa
#define COEFF_MD 0xb
#define COEFF_LO 0xc
#define RAM_ADR 0xd
#define CONFIG 0xf
#define OUTPUT3 0x0 /* Most significant byte of result */
#define OUTPUT2 0x1
#define OUTPUT1 0x2 /* Two least significant bytes are */
#define OUTPUT0 0x3 /* unused since rounded to 16 bits */
#define LTAP1_HI 0x4 /* unused */
#define LTAP1_LO 0x5 /* unused */
#define LTAP2_HI 0x6 /* unused */
#define LTAP2_LO 0x7 /* unused */
#define LEAKAGE 0x0 /* Addresses (hex) of DSP56200 regs, bank 1 */
#define FTL 0x1
#define LKG_VAL 0x00 /* Values (hex) written to the DSP56200 regs */
#define FTL_VAL 0xff /* 256 taps */
#define DCONFIG_0 0x98 /* Updates disabled, Selects bank 0 */
#define DCONFIG_1 0x99 /* Updates disabled, Selects bank 1 */
#define ECONFIG_0 0x90 /* Updates enabled, Selects bank 0 */
#define KVAL_HI 0x04
#define KVAL_LO 0x00 /* It may be desirable to make the K
register a variable so it can be
updated every sample period. */
/*** MAIN PROGRAM ***/
main() {
/********************************************************************\
* *
* This program is an example of the software used by a host *
* processor to service a DSP56200 configured as an adaptive *
* filter. Three functions are performed: *
* *
* 1. Initialize User's System and Configure the DSP56200. *
* 2. Zero the Coeff and Data RAMs of the DSP56200. *
* 3. Run the Adaptive Filter in a real-time environment. *
* *
* Things to watch for when setting up an adaptive filter system: *
* *
* - There must be NO GLITCHES on the DSP56200's START pin. *
* - The SEI pin must be directly wired to the SSO pin. *
* - The value of the K register must not be too large. *
* - If codecs are used for the A/D or D/A conversion, see *
* comments in the routines "send_da()"and "get_ad()". *
* - If offset binary A/Ds or D/As are used, see comments *
* in the subroutines "send_da()" and "get_ad()". *
* *
* Note: The program assumes that the variable type "int" is at *
* least 16 bits wide. *
* *
\********************************************************************/
/* Program Declarations */
int tap; /* filter tap number */
/* Initialize System */
/* Here the user first initializes any other components of the */
/* adaptive filtering system which require initialization. The */
/* DSP56200 is then initialized using the program code below. */
/* Reset and Configure the DSP56200 */
wait_for_start(); /* This is done to synchronize */
/* the program up to the system. */
/* Ensures that no writes occur */
/* when the DSP56200's START pin */
/* receives a rising edge. */
wrbyte(DCONFIG_1, CONFIG); /* Configuration: */
/* - Single Adaptive Filter */
/* - Not Cascaded */
/* - 16 Bit Rounding */
/* - Coeff Update Disabled */
/* - DC Tap Disabled */
/* - Leakage Disabled */
/* - Register Bank 1 Selected */
wrbyte(FTL_VAL, FTL); /* Writing this reg also resets */
/* the chip at the beginning */
/* of the next sample period, */
/* which destroys any previous */
/* contents of the Data RAM. */
wrbyte(LKG_VAL, LEAKAGE);
wrbyte(DCONFIG_0, CONFIG); /* Switch to register bank 0 */
wrbyte(KVAL_HI, K_HI);
wrbyte(KVAL_LO, K_LO);
/* Presently for initialization, there are fourteen writes */
/* which the host processor must perform in one sample */
/* period. If all these writes cannot be performed in one */
/* sample period, a call to the routine "wait_for_start()" */
/* can be inserted here, and will reduce the number of */
/* writes down to a maximum of eight in one sample period. */
/* Initialize the DSP56200's Coefficient and Data RAMS */
wrbyte(0, X1_HI);
wrbyte(0, X1_LO);
wrbyte(0, D_HI);
wrbyte(0, D_LO);
wrbyte(0, COEFF_HI); /* Coeff_RAM[0] = 0 */
wrbyte(0, COEFF_MD);
wrbyte(0, COEFF_LO);
wrbyte(0, RAM_ADR); /* autoincrements w/ each START */
wait_for_start();
for (tap=1; tap<=FTL_VAL; tap=tap+1) {
wrbyte(0, COEFF_HI); /* Coeff_RAM[tap] = 0 */
wrbyte(0, COEFF_MD);
wrbyte(0, COEFF_LO);
/* Note that the Data RAM is also */
/* cleared since the DSP56200's X1 */
/* reg is set to "0", resulting in */
/* "0"s being "shifted" into the */
/* filter's Data RAM (delay line) */
/* every sample period. */
wait_for_start();
}
/* Enable Coefficient Updates -toggles bit 3 to a "0" */
wrbyte(ECONFIG_0, CONFIG);
/* Run the Adaptive Filter in Real-time */
prealtime();
}
/*** SUBROUTINES ***/
/* PREALTIME */
prealtime()
{
/****************************************************************\
* *
* This routine performs the I/O servicing required when the *
* DSP56200 is processing real-time samples. Every sample *
* period (signified by the reception of a rising edge on the *
* DSP56200's START pin), the host processor sends two new *
* samples to the DSP56200, and reads out a result from the *
* DSP56200. *
* *
* This routine is used only in polled I/O systems. *
* *
* Note: The routine assumes that the variable type "int" is *
* at least 16 bits wide. *
* *
* Also: The DSP56200 outputs "-1 * error". If the correct *
* sign for the error term is required, then the host *
* processor must perform a 2's complement operation *
* on the 16 bit value read from the DSP56200's OUTPUT *
* register (bytes 3 and 2). *
* *
* Also: It is important that execution of the code inside the *
* while loop completes before the next sample period *
* begins. This guarantees that the start of the next *
* sample period is never missed because the program will *
* then be in the subroutine "wait_for_start()", polling *
* for the rising edge of the START signal. *
* *
\****************************************************************/
/* Subroutine Declarations */
int x1, d, out; /* see Figure 2 */
while (FOREVER) { /* infinite loop */
/* Poll for Reception of the START signal */
wait_for_start();
/* Host Now Services the DSP56200 Since START Has Been Received */
/* Read New Samples from the A/Ds and Write to the DSP56200 */
x1 = get_ad(1);
d = get_ad(2);
wrbyte((x1>>8) & 0x0ff, X1_HI); /* writes upper byte */
wrbyte( x1 & 0x0ff, X1_LO); /* writes lower byte */
wrbyte((d>>8) & 0x0ff, D_HI); /* writes upper byte */
wrbyte( d & 0x0ff, D_LO); /* writes lower byte */
/* Read Error Term from the 56200 and Write to the D/A */
out = rdbyte(OUTPUT3);
out = out << 8; /* move to upper byte */
out = out + (0x0ff & rdbyte(OUTPUT2));
send_da(out);
}
}
/* WRBYTE */
wrbyte(val,adr)
int val, adr;
{
/**************************************************************\
* *
* This subroutine writes one byte to the DSP56200 register *
* specified by "adr". *
* Note that the correct register bank has already been *
* selected (defined by the LSB of the Configuration reg). *
* *
* This subroutine could be defined as a macro for faster *
* execution. *
* *
* Inputs: *
* val = bytewide value to be written to the DSP56200 *
* adr = address of the DSP56200 register to be written *
* *
\**************************************************************/
/* Actual program code depends on the user's system. */
}
/* RDBYTE */
rdbyte(adr)
int adr;
{
/**************************************************************\
* *
* This subroutine reads one byte from the DSP56200 register *
* specified by "adr". *
* Note that the correct register bank has already been *
* selected (defined by the LSB of the Configuration reg). *
* *
* This subroutine could be defined as a macro for faster *
* execution. *
* *
* Inputs: *
* adr = address of the DSP56200 register to be read *
* *
* Outputs: *
* The routine returns the byte read from the DSP56200 *
* *
\**************************************************************/
int valread;
/* Actual program code depends on the user's system. */
return(valread);
}
/* GET_AD */
get_ad(devnum)
int devnum;
{
/******************************************************************\
* *
* This subroutine returns a 16 bit value read from one of the *
* two A/D converters in the filtering system. *
* *
* Inputs: *
* devnum = A/D Converter number: 1 = x1 input, 2 = d input. *
* *
* Outputs: *
* The routine returns the value read from the selected A/D. *
* *
\******************************************************************/
int ad_val;
/* Actual program code depends on the user's system. */
/* If a codec is used for A/D conversion, the 8 bit companded */
/* sample must be converted into a 12 bit linear quantity and */
/* then sign extended to 16 bits. */
/* If the converter uses an offset binary format, it may be */
/* necessary to invert the sign bit (and any sign extension */
/* bits) to obtain a 2's complement number. */
return(ad_val);
}
/* SEND_DA */
send_da(val)
int val;
{
/**************************************************************\
* *
* This subroutine sends a value to a D/A converter where it *
* gets converted to an analog signal. *
* *
* Inputs: *
* val = value to be sent to the D/A converter *
* *
\**************************************************************/
/* Actual program code depends on the user's system. */
/* If a codec is used for D/A conversion, the 16 bit linear */
/* sample must be converted into a 8 bit companded quantity. */
/* If the converter uses an offset binary format, it may be */
/* necessary to invert the sign bit (and any sign extension */
/* bits) to obtain a number in offset binary format. */
}
/* WAIT_FOR_START */
wait_for_start()
{
/********************************************************************\
* *
* This routine polls a general purpose input pin for a "1", *
* which indicates that a rising edge has arrived at the START pin *
* of the DSP56200 and that new samples are ready to be processed. *
* *
* Note: It may be necessary to verify that the START signal has *
* returned to a "0" before polling for a "1". *
* *
* Note: It is important that the program has completed other *
* processing and is waiting in this loop when the START *
* signal arrives so that no samples are lost. *
* *
\********************************************************************/
int pin;
pin = get_pin();
while (pin == 0); /* loops until "1" found on pin */
pin = get_pin();
}
/* GET_PIN */
get_pin()
{
/*****************************************************************\
* *
* Returns the value read (0 or 1) from a general purpose input *
* pin which is tied directly to the DSP56200's START pin. *
* *
\*****************************************************************/
/* Actual program code depends on the user's system. */
}